
#include "resource_manager.h"
#include "utility.h"
#include <sstream>

ResourceManager::ResourceManager()
{

}

ResourceManager::~ResourceManager()
{
	log_info("~ResourceManager");
	for (imageMapType::iterator iter = imageMap.begin(); iter != imageMap.end(); ++iter)
	{
		if (iter->second != NULL)
		{
			std::stringstream logLine;
			logLine << "~ResourceManager(): Freeing image: " << iter->first << " (" << iter->second->w << "x" << iter->second->h << ")";
			log_info(logLine.str());
			SDL_FreeSurface(iter->second);
			iter->second = NULL;
		}
	}
	for (soundMapType::iterator iter = soundMap.begin(); iter != soundMap.end(); ++iter)
	{
		if (iter->second != NULL)
		{
			std::stringstream logLine;
			logLine << "~ResourceManager(): Freeing sound: " << iter->first;
			log_info(logLine.str());
			Mix_FreeChunk(iter->second);
			iter->second = NULL;
		}
	}
	for (musicMapType::iterator iter = musicMap.begin(); iter != musicMap.end(); ++iter)
	{
		if (iter->second != NULL)
		{
			std::stringstream logLine;
			logLine << "~ResourceManager(): Freeing music: " << iter->first;
			log_info(logLine.str());
			Mix_FreeMusic(iter->second);
			iter->second = NULL;
		}
	}
}

//Image functions

//Get the image with given filename, either from cache or by loading from file
//Alpha format only used when not in cache
SDL_Surface* ResourceManager::GetImage(std::string imageName, bool alphaFormat)
{
	//standardize name as what loaded it
	imageName = format_path(imageName);

	//Is image in cache?
	imageMapType::iterator it = imageMap.find(imageName);

	//If found in cache, return image
	if (it != imageMap.end())
		return it->second;

	SDL_Surface* image = NULL;
	image = load_image(imageName, alphaFormat);

	if (image != NULL)
		imageMap[imageName] = image;
	else
		log_info(std::string("ResourceManager::GetImage(): image not found: ") + imageName);

	return image;
}

//Add non-filename based image to resource manager. it will be cleaned up by manager
void ResourceManager::SetImage(std::string imageName, SDL_Surface* image)
{
	//standardize image name
	imageName = format_path(imageName);

	imageMapType::iterator it = imageMap.find(imageName);

	if (it != imageMap.end())
	{
		std::stringstream logLine;
		logLine << "ResourceManager::SetImage(): Freeing image: " << it->first << " dimensions w: " << it->second->w << " h: " << it->second->h;
		log_info(logLine.str());
		SDL_FreeSurface(it->second);
		it->second = NULL;
	}

	if (image != NULL)
	{
		std::stringstream logLine;
		logLine << "ResourceManager::SetImage(): Setting image: " << imageName << " dimensions w: " << image->w << " h: " << image->h;
		log_info(logLine.str());
		imageMap[imageName] = image;
	}
	else
	{
		log_info(std::string("ResourceManager::SetImage(): Removing resource key: ") + imageName);
		imageMap.erase(imageName);
	}
}

void ResourceManager::RemoveImage(std::string imageName)
{
	imageName = format_path(imageName);

	imageMapType::iterator it = imageMap.find(imageName);

	if (it != imageMap.end())
	{
		SDL_FreeSurface(it->second);
		it->second = NULL;
		imageMap.erase(it);
	}
}


//Sound functions

//Get the image with given filename, either from cache or by loading from file
//Alpha format only used when not in cache
Mix_Chunk* ResourceManager::GetSound(std::string soundName)
{
	//standardize name as what loaded it
	soundName = format_path(soundName);
    
	//Is image in cache?
	soundMapType::iterator it = soundMap.find(soundName);
    
	//If found in cache, return image
	if (it != soundMap.end())
		return it->second;
    
	Mix_Chunk* sound = NULL;
	sound = Mix_LoadWAV(soundName.c_str());
    
	if (sound != NULL)
		soundMap[soundName] = sound;
	else
		log_info(std::string("ResourceManager::GetSound(): sound not found: ") + soundName);
    
	return sound;
}

//Add non-filename based sound to resource manager. it will be cleaned up by manager
void ResourceManager::SetSound(std::string soundName, Mix_Chunk* sound)
{
	//standardize image name
	soundName = format_path(soundName);
    
	soundMapType::iterator it = soundMap.find(soundName);
    
	if (it != soundMap.end())
	{
		std::stringstream logLine;
		logLine << "ResourceManager::SetSound(): Freeing sound: " << it->first;
		log_info(logLine.str());
		Mix_FreeChunk(it->second);
		it->second = NULL;
	}
    
	if (sound != NULL)
	{
		std::stringstream logLine;
		logLine << "ResourceManager::SetSound(): Setting sound: " << soundName;
		log_info(logLine.str());
		soundMap[soundName] = sound;
	}
	else
	{
		log_info(std::string("ResourceManager::SetSound(): Removing resource key: ") + soundName);
		soundMap.erase(soundName);
	}
}

void ResourceManager::RemoveSound(std::string soundName)
{
	soundName = format_path(soundName);
    
	soundMapType::iterator it = soundMap.find(soundName);
    
	if (it != soundMap.end())
	{
		Mix_FreeChunk(it->second);
		it->second = NULL;
		soundMap.erase(it);
	}
}

//Music functions

//Get the music with given filename, either from cache or by loading from file
//Alpha format only used when not in cache
Mix_Music* ResourceManager::GetMusic(std::string musicName)
{
	//standardize name as what loaded it
	musicName = format_path(musicName);
    
	//Is music in cache?
	musicMapType::iterator it = musicMap.find(musicName);
    
	//If found in cache, return music
	if (it != musicMap.end())
		return it->second;
    
	Mix_Music* music = NULL;
	music = Mix_LoadMUS(musicName.c_str());
    
	if (music != NULL)
		musicMap[musicName] = music;
	else
		log_info(std::string("ResourceManager::GetMusic(): music not found: ") + musicName);
    
	return music;
}

//Add non-filename based music to resource manager. it will be cleaned up by manager
void ResourceManager::SetMusic(std::string musicName, Mix_Music* music)
{
	//standardize music name
	musicName = format_path(musicName);
    
	musicMapType::iterator it = musicMap.find(musicName);
    
	if (it != musicMap.end())
	{
		std::stringstream logLine;
		logLine << "ResourceManager::SetMusic(): Freeing music: " << it->first;
		log_info(logLine.str());
		Mix_FreeMusic(it->second);
		it->second = NULL;
	}
    
	if (music != NULL)
	{
		std::stringstream logLine;
		logLine << "ResourceManager::SetMusic(): Setting music: " << musicName;
		log_info(logLine.str());
		musicMap[musicName] = music;
	}
	else
	{
		log_info(std::string("ResourceManager::SetMusic(): Removing resource key: ") + musicName);
		musicMap.erase(musicName);
	}
}

void ResourceManager::RemoveMusic(std::string musicName)
{
	musicName = format_path(musicName);
    
	musicMapType::iterator it = musicMap.find(musicName);
    
	if (it != musicMap.end())
	{
		Mix_FreeMusic(it->second);
		it->second = NULL;
		musicMap.erase(it);
	}
}
